/**
 * 
 */
package br.embedded.socialapp.business;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import br.embedded.socialapp.data.DataFacade;
import br.embedded.socialapp.domain.FriendshipInfo;
import br.embedded.socialapp.domain.GraphBuilder;
import br.embedded.socialapp.domain.User;
import br.embedded.socialapp.domain.Usuario;

/**
 * @author daniel
 *
 */
public class FriendManager
{
	private static FriendManager instance;
	
	private FriendManager()
	{
	}
	
	public static FriendManager getInstance()
	{
		if (instance == null)
			instance = new FriendManager();
		return instance;
	}
	
	public User fetchPerson(String socialNetworkId, String socialNetwork)
	{
		SocialNetworkHandler socialNetworkHandler = new SocialNetworkHandler(socialNetwork);
		return socialNetworkHandler.fetchPerson(socialNetworkId);
	}
	
	public ArrayList<User> fetchFriends(String socialNetworkId, String socialNetwork, boolean detailed)
	{
		Usuario u = UserManager.getInstance().getUserById("'"+socialNetworkId+"'").get(0);
		List<GraphBuilder> graphs = DataFacade.getInstance().getUsers();
		
		if (socialNetwork.equalsIgnoreCase("ORKUT_SANDBOX") && graphs.get(0) != null)
			return (ArrayList<User>) getFriends(u.getLogin(), socialNetworkId, graphs.get(0));
		if (socialNetwork.equalsIgnoreCase("MYSPACE") && graphs.get(1) != null)
			return (ArrayList<User>) getFriends(u.getLogin(), socialNetworkId, graphs.get(1));
		if (socialNetwork.equalsIgnoreCase("ALL") && graphs.get(2) != null)
			return (ArrayList<User>) getFriends(u.getLogin(), socialNetworkId, graphs.get(2));
		
		Hashtable<String, User> result = new Hashtable<String, User>();
		
		SocialNetworkHandler socialNetworkHandler = new SocialNetworkHandler(socialNetwork);
		
		List<User> friendList = socialNetworkHandler.fetchFriends(socialNetworkId, detailed, 1);
		
		for (User friend : friendList) 
		{
			if (!friend.getId().equals(socialNetworkId) && !result.containsKey(friend.getId()))
				result.put(friend.getId(), friend);
			
			List<User> foafList = socialNetworkHandler.fetchFriends(friend.getId(), detailed, 2);
			
			for (User foaf : foafList)
			{
				if (!foaf.getId().equals(socialNetworkId) && !result.containsKey(foaf.getId()))
					result.put(foaf.getId(), foaf);
			}
		}
		return new ArrayList<User>(result.values());
	}
	
	public List<User> getFriends(Usuario usuario)
	{
		List<User> friendList = new ArrayList<User>();
		
		List<GraphBuilder> graphs = DataFacade.getInstance().getUsers();
		
		for (GraphBuilder graph : graphs)
			friendList.addAll(getFriends(usuario.getLogin(), graph.getNetwork(), graph));
		
		//List<List<User>> list = DataFacade.getInstance().getFriends(usuario.getLogin());
		
		//friendList.addAll(list.get(0));
		//friendList.addAll(list.get(1));
		
		
/*		if (usuario.getSocialNetworks().size() > 0)
			friendList.addAll(FriendManager.getInstance().fetchFriends(usuario.getSocialNetworks().get(0), "ORKUT_SANDBOX", false));
		if (usuario.getSocialNetworks().size() > 1)
			friendList.addAll(FriendManager.getInstance().fetchFriends(usuario.getSocialNetworks().get(1), "MYSPACE", false));
*/		
		Collections.sort(friendList);
		return friendList;
	}
	
	private List<User> getFriends(String login, String id, GraphBuilder graphBuilder)
	{
		List<User> friendList = new ArrayList<User>();
		GraphCache graphCache = new GraphCache(graphBuilder.getGraph());
		graphCache.cacheFriendshipLevels();

		int level = 1;

		while (graphCache.containsNeighboursAtLevel(login, level)) {
			
			Set<User> tmpList = graphCache.getNeighboursAtLevel(login, level);
			
			for (User user : tmpList) {
				user.setFriendshipInfo(new FriendshipInfo(login, id, graphBuilder.getNetwork(), level));
				friendList.add(user);
			}
			++level;
		}
		Collections.sort(friendList);
		
		return friendList;
	}
}
